package com.linxiao.hrcrm.service.impl;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SM4;
import com.linxiao.hrcrm.domain.CrmCustomerProject;
import com.linxiao.hrcrm.domain.CrmCustomerRelationship;
import com.linxiao.hrcrm.service.ICrmCustomerProjectService;
import com.linxiao.hrcrm.service.ICrmCustomerRelationshipService;
import com.linxiao.hrcrm.vo.AllocationRequest;
import com.linxiao.hrcrm.vo.CustomerVO;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.linxiao.hrcrm.mapper.CrmCustomerMapper;
import com.linxiao.hrcrm.domain.CrmCustomer;
import com.linxiao.hrcrm.service.ICrmCustomerService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Validator;


/**
 * 客户信息Service业务层处理
 *
 * @author zhoudong
 * @date 2024-01-03
 */
@Service
public class CrmCustomerServiceImpl implements ICrmCustomerService {

    private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);

    @Resource
    private CrmCustomerMapper crmCustomerMapper;
    @Value("${secure.aes.mobile}")
    private String aesKey;
    @Value("${customer.user.deptId}")
    private Long customerUserDeptId;
    @Value("${customer.user.postId}")
    private Long customerUserPostId;
    @Value("${customer.user.roleId}")
    private Long customerUserRoleId;
    @Resource
    private ISysUserService userService;
    @Resource
    private ICrmCustomerRelationshipService crmCustomerRelationshipService;
    @Resource
    protected Validator validator;
    @Resource
    private ICrmCustomerProjectService crmCustomerProjectService;

    /**
     * 查询客户信息
     *
     * @param id 客户信息主键
     * @return 客户信息
     */
    @Override
    public CrmCustomer selectCrmCustomerById(Long id) {
        return crmCustomerMapper.selectCrmCustomerById(id);
    }

    /**
     * 查询客户信息列表
     *
     * @param crmCustomer 客户信息
     * @return 客户信息
     */
    @Override
    public List<CrmCustomer> selectCrmCustomerList(CrmCustomer crmCustomer) {
        return crmCustomerMapper.selectCrmCustomerList(crmCustomer);
    }

    /**
     * 新增客户信息
     *
     * @param crmCustomer 客户信息
     * @return 结果
     */
    @Transactional
    @Override
    public int insertCrmCustomer(CrmCustomer crmCustomer) {
        // 根据手机号+商户ID，查询客户是否存在
        CrmCustomer dbResult = findByMchIdAndEncryptedPhoneNumber(crmCustomer.getMchId(), crmCustomer.getPhoneNumber());
        if (dbResult != null) {
            throw new UtilException("当前客户已存在，不可再次录入");
        }
        // 保存到用户表，用于登录小程序
        if (StrUtil.isBlank(crmCustomer.getMemberId())) {
            SysUser user = new SysUser();
            user.setPhonenumber(crmCustomer.getPhoneNumber());
            boolean b = userService.checkPhoneUnique(user);
            if (b) {
                // 不存在，去注册
                user.setDeptId(customerUserDeptId);
                user.setPostIds(new Long[]{customerUserPostId});
                user.setRoleId(customerUserRoleId);
                user.setUserName(customerUserDeptId + crmCustomer.getPhoneNumber());
                user.setPhonenumber(crmCustomer.getPhoneNumber());
                user.setIsSyncCreateCno(0);
                user.setNickName(StrUtil.isBlank(crmCustomer.getCustomerName()) ? user.getPhonenumber() : crmCustomer.getCustomerName());
                user.setCreateBy("system");
                userService.insertUser(user);
            } else {
                // 已经存在，直接使用
                user = userService.selectUserByPhonenumber(crmCustomer.getPhoneNumber());
            }
            crmCustomer.setMemberId(user.getUserId() + "");
        } else {
            // 验证memberId
            SysUser user = userService.selectUserById(crmCustomer.getMchId());
            if (user == null) {
                throw new UtilException("memberId有误，如果是新客户，请勿填写memberId");
            }
            crmCustomer.setMemberId(user.getUserId() + "");
        }

        // 国密对称加密
        /*SM4 sm4 = SmUtil.sm4(aesKey.getBytes(StandardCharsets.UTF_8));
        String encryptedPhoneNumber = sm4.encryptHex(crmCustomer.getPhoneNumber());*/
        String encryptedPhoneNumber = crmCustomer.getPhoneNumber();


        // 补充昵称
        if (StrUtil.isBlank(crmCustomer.getNickname())) {
            crmCustomer.setNickname(crmCustomer.getCustomerName());
        }

        

        LoginUser loginUser = SecurityUtils.getLoginUser();
        crmCustomer.setCreateBy(loginUser.getUser().getNickName());
        crmCustomer.setEncryptedPhoneNumber(encryptedPhoneNumber);
        crmCustomer.setCreateTime(DateUtils.getNowDate());

        int result = crmCustomerMapper.insertCrmCustomer(crmCustomer);

        // 项目ID不为空，则保存工人和项目的对应关系
        ThreadUtil.execAsync(() -> {
            if (StrUtil.isNotBlank(crmCustomer.getProjectId())) {
                CrmCustomerProject crmCustomerProject = new CrmCustomerProject();
                crmCustomerProject.setMchId(crmCustomer.getMchId());
                crmCustomerProject.setProjectId(Long.parseLong(crmCustomer.getProjectId()));
                crmCustomerProject.setCustomerId(crmCustomer.getId());
                crmCustomerProjectService.insertCrmCustomerProject(crmCustomerProject);
            }
        });

        return result;
    }

    /**
     * 修改客户信息
     *
     * @param crmCustomer 客户信息
     * @return 结果
     */
    @Override
    public int updateCrmCustomer(CrmCustomer crmCustomer) {
        LoginUser loginUser = SecurityUtils.getLoginUser();

        crmCustomer.setUpdateBy(loginUser.getUser().getNickName());
        crmCustomer.setLastContactTime(DateUtils.getNowDate());
        crmCustomer.setUpdateTime(DateUtils.getNowDate());
        return crmCustomerMapper.updateCrmCustomer(crmCustomer);
    }

    /**
     * 批量删除客户信息
     *
     * @param ids 需要删除的客户信息主键
     * @return 结果
     */
    @Override
    public int deleteCrmCustomerByIds(Long[] ids) {
        return crmCustomerMapper.deleteCrmCustomerByIds(ids);
    }

    /**
     * 删除客户信息信息
     *
     * @param id 客户信息主键
     * @return 结果
     */
    @Override
    public int deleteCrmCustomerById(Long id) {
        return crmCustomerMapper.deleteCrmCustomerById(id);
    }

    /**
     * 根据商户ID和手机号密文获取客户
     * @param mchId
     * @param phoneNumber
     * @return
     */
    @Override
    public CrmCustomer findByMchIdAndEncryptedPhoneNumber(Long mchId, String phoneNumber) {
        /*SM4 sm4 = SmUtil.sm4(aesKey.getBytes(StandardCharsets.UTF_8));
        String encryptedPhoneNumber = sm4.encryptHex(phoneNumber);*/
        String encryptedPhoneNumber = phoneNumber;

        CrmCustomer query = new CrmCustomer();
        query.setMchId(mchId);
        query.setEncryptedPhoneNumber(encryptedPhoneNumber);
        List<CrmCustomer> crmCustomers = selectCrmCustomerList(query);
        if (CollUtil.isNotEmpty(crmCustomers)) {
            return crmCustomers.get(0);
        }
        return null;
    }

    /**
     * 查询customerVO
     * @param customerId
     * @param employeeId
     * @param mchId
     * @return
     */
    @Override
    public CustomerVO getCustomerVO(Long customerId, Long mchId, Long employeeId) {
        CustomerVO customerVO = new CustomerVO();
        CrmCustomer crmCustomer = selectCrmCustomerById(customerId);
        customerVO.setCustomer(crmCustomer);
        if (crmCustomer == null) {
            throw new UtilException("客户不存在！");
        }

        CrmCustomerRelationship query = new CrmCustomerRelationship();
        query.setCustomerId(customerId);
        query.setMchId(mchId);
        List<CrmCustomerRelationship> crmCustomerRelationships = crmCustomerRelationshipService.selectCrmCustomerRelationshipList(query, Boolean.FALSE);
        // 销售列表
        customerVO.setRelationships(crmCustomerRelationships);

        // 当前销售
        if (employeeId != null && employeeId != 0L) {
            crmCustomerRelationships.parallelStream().forEach(crmCustomerRelationship -> {
                if (crmCustomerRelationship.getEmployeeId() == employeeId) {
                    customerVO.setDefaultRelationship(crmCustomerRelationship);
                }
            });
        }

        return customerVO;
    }

    /**
     * 客户导入
     * @param customerList
     * @param updateSupport
     * @param operName
     * @param mchId
     * @return
     */
    @Override
    public String customerList(List<CrmCustomer> customerList, boolean updateSupport, String operName, Long mchId) {
        if (StringUtils.isNull(customerList) || customerList.size() == 0) {
            throw new ServiceException("导入客户数据不能为空！");
        }

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (CrmCustomer customer : customerList) {
            try {
                // 验证是否存在这个客户
                CrmCustomer c = selectByPhoneNumberAndMchId(customer.getPhoneNumber(), mchId);
                if (StringUtils.isNull(c)) {
                    BeanValidators.validateWithException(validator, customer);
                    if (StrUtil.isBlank(customer.getSource())) {
                        customer.setSource("Excel资源导入");
                    }
                    if (StrUtil.isBlank(customer.getNickname())) {
                        customer.setNickname(customer.getCustomerName());
                    }
                    this.insertCrmCustomer(customer);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、账号 " + customer.getPhoneNumber() + " 导入成功");
                } else if (Boolean.TRUE.equals(updateSupport)) {
                    BeanValidators.validateWithException(validator, customer);
                    successNum++;
                    this.updateCrmCustomer(customer);
                    successMsg.append("<br/>" + successNum + "、账号 " + customer.getPhoneNumber() + " 更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、账号 " + customer.getPhoneNumber() + " 已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、账号 " + customer.getPhoneNumber() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 根据手机号和商户ID查询客户
     * @param phoneNumber
     * @param mchId
     * @return
     */
    public CrmCustomer selectByPhoneNumberAndMchId(String phoneNumber, Long mchId) {
        CrmCustomer query = new CrmCustomer();
        query.setPhoneNumber(phoneNumber);
        query.setMchId(mchId);
        List<CrmCustomer> crmCustomers = crmCustomerMapper.selectCrmCustomerList(query);
        if (CollUtil.isNotEmpty(crmCustomers)) {
            return crmCustomers.get(0);
        }
        return null;
    }

    /**
     * 客户分配
     * @param allocationRequest
     * @return
     */
    @Override
    public int allocationCustomer(AllocationRequest allocationRequest) {
        // 1、验证商户下，待分配的客户总数
        int toBeAllocationCount = crmCustomerMapper.toBeAllocationCount(allocationRequest.getMchId());
        if (toBeAllocationCount < allocationRequest.getAllocationNum()) {
            throw new UtilException("分配数量不可大于未分配数量");
        }

        // 2、分配，随机分配或者顺序分配，0-顺序分配，1-随机分配
        List<CrmCustomer> allocationExtracts = crmCustomerMapper.allocationExtract(allocationRequest);

        List<Long> ids = allocationExtracts.stream().map(e -> e.getId()).collect(Collectors.toList());

        int allocationResult = crmCustomerRelationshipService.allocation(allocationRequest.getMchId(),
                allocationRequest.getEmployeeId(), ids);

        return allocationResult;
    }

    /**
     * 获取待分配的总数
     * @param mchId
     * @return
     */
    @Override
    public int toBeAllocationCount(Long mchId) {
        return crmCustomerMapper.toBeAllocationCount(mchId);
    }

    /**
     * 根据memberId和mchId查询
     * @param mchId
     * @param userId
     * @return
     */
    @Override
    public CrmCustomer selectCrmCustomerByMemberId(Long mchId, Long userId) {
        CrmCustomer query = new CrmCustomer();
        query.setMchId(mchId);
        query.setMemberId(userId + "");
        List<CrmCustomer> crmCustomers = crmCustomerMapper.selectCrmCustomerList(query);
        if (CollUtil.isEmpty(crmCustomers)) {
            return null;
        }
        return crmCustomers.get(0);
    }
}
